home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
bit
/
src
/
forms
/
FORMS
/
dial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
5KB
|
197 lines
/*
* dial.c
*
* Forms Object class: DIAL
*
* Written by: Mark Overmars
*
* Version 2.1 a
* Date: Sep 29, 1992
*/
#include <malloc.h>
#include <math.h>
#include "gl/gl.h"
#include <sys/types.h>
#include "forms.h"
/* The special information for dial. */
typedef struct {
float min; /* minimal value of dial */
float max; /* maximal value of dial */
float val; /* current value of dial */
float step; /* step size */
int always; /* whether always returning value */
} SPEC;
static void draw_dial(FL_OBJECT *ob)
/* Draws a dial */
{
float min,max,val;
int angle;
min = ((SPEC *)(ob->spec))->min;
max = ((SPEC *)(ob->spec))->max;
val = ((SPEC *)(ob->spec))->val;
angle = (int) (2700.0*(val-min)/(max-min));
fl_drw_box(ob->boxtype,ob->x,ob->y,ob->w,ob->h,FL_DIAL_TOPCOL,FL_DIAL_BW);
pushmatrix();
translate(ob->x + ob->w/2.0 -0.5, ob->y+ob->h/2.0 -0.5,0.0);
if (ob->boxtype == FL_NO_BOX)
scale(ob->w,ob->h,1.0);
else
scale(0.9*ob->w,0.9*ob->h,1.0);
fl_color(ob->col1);
circf(0.0,0.0,0.5);
fl_color(BLACK);
circ(0.0,0.0,0.5);
rotate(-angle,'Z');
if (ob->type == FL_NORMAL_DIAL)
{
fl_color(ob->col2);
circf(-0.20,-0.20,0.07);
fl_color(BLACK);
circ(-0.20,-0.20,0.07);
}
else
{
fl_color(ob->col2);
pmv2(0.0,0.0);
pdr2(-0.04,0.0);
pdr2(-0.25,-0.25);
pdr2(0.0,-0.04);
pclos();
fl_color(BLACK);
move2(0.0,0.0);
draw2(-0.04,0.0);
draw2(-0.25,-0.25);
draw2(0.0,-0.04);
draw2(0.0,0.0);
}
popmatrix();
fl_drw_text_beside(ob->align,ob->x,ob->y,ob->w,ob->h,
ob->lcol,ob->lsize,ob->lstyle,ob->label);
}
#define PI 3.14159
static int handle_mouse(FL_OBJECT *ob,float mousex,float mousey)
/* Handle a mouse position change */
{
SPEC *sp = (SPEC *) ob->spec;
double oldval,min,max,val;
double mx,my;
double angle;
min = sp->min;
max = sp->max;
val = sp->val;
oldval = val;
mx = mousex - (ob->x + ob->w/2.0);
my = mousey - (ob->y + ob->h/2.0);
if (mx == 0.0 && my == 0.0) return 0;
if (fabs(mx)>fabs(my))
{
angle = atan(my/mx);
if (mx>0) angle = 1.25*PI - angle;
else angle = 0.25*PI - angle;
}
else
{
angle = atan(mx/my);
if (my>0) angle = 0.75*PI + angle;
else angle = -0.25*PI + angle;
}
if (angle<-0.25*PI) angle += 2.0*PI;
val = min + (max-min)*angle/(1.5*PI);
if (sp->step != 0.0) val = (int) (val/sp->step +0.5) * sp->step;
if (val < min) val = min;
if (val > max) val = max;
if (fabs(val-oldval)<(max-min)/2.0)
{
sp->val = val;
if (val-oldval > 0.0001*(max-min) || val-oldval < -0.0001*(max-min))
{ fl_redraw_object(ob); return 1; }
}
return 0;
}
static int handle_dial(FL_OBJECT *ob,int event,float mx,float my,char key)
/* Handles an event */
{
SPEC *sp = (SPEC *) ob->spec;
switch (event)
{
case FL_DRAW:
draw_dial(ob);
return 0;
case FL_PUSH:
case FL_MOUSE:
return ( handle_mouse(ob,mx,my) && sp->always);
case FL_RELEASE:
return (! sp->always);
case FL_FREEMEM:
free(ob->spec);
return 0;
}
return 0;
}
/*------------------------------*/
FL_OBJECT *fl_create_dial(int type,float x,float y,float w,float h,char label[])
/* creates an object */
{
FL_OBJECT *ob;
ob = fl_make_object(FL_DIAL,type,x,y,w,h,label,handle_dial);
ob->col1 = FL_DIAL_COL1;
ob->col2 = FL_DIAL_COL2;
ob->align = FL_DIAL_ALIGN;
ob->lcol = FL_DIAL_LCOL;
ob->spec = (int *) fl_malloc(sizeof(SPEC));
((SPEC *)(ob->spec))->min = 0.0;
((SPEC *)(ob->spec))->max = 1.0;
((SPEC *)(ob->spec))->val = 0.5;
((SPEC *)(ob->spec))->step = 0.0;
((SPEC *)(ob->spec))->always = TRUE;
return ob;
}
FL_OBJECT *fl_add_dial(int type, float x, float y, float w, float h, char label[])
/* Adds an object */
{
FL_OBJECT *ob;
ob = fl_create_dial(type,x,y,w,h,label);
fl_add_object(fl_current_form,ob);
return ob;
}
void fl_set_dial_value(FL_OBJECT *ob,float val)
{
((SPEC *)(ob->spec))->val = val;
fl_redraw_object(ob);
}
void fl_set_dial_bounds(FL_OBJECT *ob,float min,float max)
{
((SPEC *)(ob->spec))->min = min;
((SPEC *)(ob->spec))->max = max;
fl_redraw_object(ob);
}
float fl_get_dial_value(FL_OBJECT *ob)
{ return ((SPEC *)(ob->spec))->val; }
void fl_get_dial_bounds(FL_OBJECT *ob,float *min,float *max)
{
*min = ((SPEC *)(ob->spec))->min;
*max = ((SPEC *)(ob->spec))->max;
}
void fl_set_dial_return(FL_OBJECT *ob, int value)
/* Sets whether to return value all the time */
{ ((SPEC *)(ob->spec))->always = value; }
void fl_set_dial_step(FL_OBJECT *ob, float value)
/* Sets the step size to which values are rounded. */
{ ((SPEC *)(ob->spec))->step = value; }